/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.ssm.changeunit.diff;

import java.util.*;
import org.apache.log4j.Logger;

/**
 *
 * @author 시리우스
 */
public class ContentMerger {
    private Logger log = Logger.getLogger(ContentMerger.class);
    
    private StringBuffer newContent;
    
    /**
     * 2개의 Content를 비교합니다.
     * 
     * @param originContent
     * @param targetContent
     * @return
     */
    public synchronized String[] merge(String[] originContent, String[] targetContent) {
        // 새로운 Content를 할당한다.
        newContent = new StringBuffer();
        
        // 현재 커서
        int cursorOfContent = 0;
        
        // 비교
        List diffs  = (new Diff(originContent, targetContent)).diff();
        
        log.debug("Difference 개수: " + diffs.size());
        
        Iterator it = diffs.iterator();
        
        while (it.hasNext()) {
            Difference diff     = (Difference)it.next();
            int        delStart = diff.getDeletedStart();
            int        delEnd   = diff.getDeletedEnd();
            int        addStart = diff.getAddedStart();
            int        addEnd   = diff.getAddedEnd();
            String     type     = delEnd != Difference.NONE && addEnd != Difference.NONE ? "change" : (delEnd == Difference.NONE ? "add" : "delete");
            
            // 추가된 경우
            if(type.equals("add")) {
                log.debug("Add. addStart: " + addStart + " addEnd: " + addEnd + " delStart: " + delStart + " delEnd: " + delEnd);
                
                // 전 자료 출력
                printLinesToStringBuffer(cursorOfContent, delStart - 1, originContent);
                
                // 추가된 자료 출력
                printLinesToStringBuffer(addStart, addEnd, targetContent);
                
                // 커서 옮김
                cursorOfContent = delStart;
            }
            // 삭제된 경우
            /*else if(type.equals("delete")) {
                log.debug("Delete. addStart: " + addStart + " addEnd: " + addEnd + " delStart: " + delStart + " delEnd: " + delEnd);
                
                // 전 자료 출력
                printLinesToStringBuffer(cursorOfContent, delStart - 1, originContent);
                
                cursorOfContent = delEnd + 1;
            }*/
            // 변경된 경우
            else if(type.equals("change")) {
                log.debug("Change. addStart: " + addStart + " addEnd: " + addEnd + " delStart: " + delStart + " delEnd: " + delEnd);
                
                printLinesToStringBuffer(cursorOfContent, delStart - 1, originContent);
                
                cursorOfContent = delEnd + 1;
                
                newContent.append(">> mine\n");
                
                printLinesToStringBuffer(delStart, delEnd, originContent);
                
                newContent.append("------\n");
                
                printLinesToStringBuffer(addStart, addEnd, targetContent);
                
                newContent.append(">> yours\n");
            }
        }
        
        printLinesToStringBuffer(cursorOfContent, originContent.length - 1, originContent);
                
        cursorOfContent = originContent.length - 1;
        
        return newContent.toString().split("\n");
    }

    /**
     * StringBuffer에 출력한다.
     * @param start
     * @param end
     * @param lines
     */
    protected void printLinesToStringBuffer(int start, int end, String[] lines)
    {
        for (int lnum = start; lnum <= end; ++lnum) {
            log.debug(lines[lnum]);
            
            newContent.append(lines[lnum] + "\n");
        }
    }
}
